﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// System.IO.Path扩展使用类
    /// </summary>
    public static class PathEx
    {
        /***********************************************************************
         * 路径示例
         * web           file:///C:/Users/zhanghn/Desktop/temlp.html             
         * local-linux   /home/yf/桌面
         * local-win     D:\tmp\test 
         ***********************************************************************/


        /// <summary>
        /// 左斜杠'\\'
        /// </summary>
        public static readonly char LeftSlash = '\\';

        /// <summary>
        /// 右斜杠 '/'
        /// </summary>
        public static readonly char RightSlash = '/';








        /// <summary>
        /// 获取主程序目录，当获取到的入口程序集为null时返回System.AppDomain.CurrentDomain.BaseDirectory
        /// </summary>
        /// <returns>主程序目录</returns>
        public static string GetEntryAssemblyDirectory()
        {
            return AppDomain.CurrentDomain.BaseDirectory;
        }



        /// <summary>
        /// 获取路径的完整路径
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns>完整路径</returns>
        public static string GetFullPath(string path)
        {
            string rootPath = Path.GetPathRoot(path);
            if (!string.IsNullOrWhiteSpace(rootPath))
            {
                return path;
            }

            rootPath = GetEntryAssemblyDirectory();
            return Combine(PathType.Local, rootPath, path);
        }

        /// <summary>
        /// 获取路径最后一步份名称
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns>路径最后一步份名称</returns>
        public static string GetLastPathName(string path)
        {
            int rootPathLength = Path.GetPathRoot(path).Length - 1;

            for (int i = path.Length - 1; i >= 0; i--)
            {
                if (path[i] == LeftSlash || path[i] == RightSlash)
                {
                    if (i >= rootPathLength)
                    {
                        return path.Substring(i + 1).Trim();
                    }
                }
            }
            return path;
        }


        /// <summary>
        /// 获取路径分隔符
        /// </summary>
        /// <param name="pathType">路径类型</param>
        /// <returns>路径分隔符</returns>
        public static char GetPathSeparatorChar(PathType pathType)
        {
            char separatorChar;
            if (pathType == PathType.Web)
            {
                separatorChar = RightSlash;
            }
            else
            {
                if (EnvironmentEx.OS == OSPlatformID.Win)
                {
                    separatorChar = LeftSlash;
                }
                else
                {
                    separatorChar = RightSlash;
                }
            }

            return separatorChar;
        }

        /// <summary>
        /// 将多个字符串拼接成路径
        /// </summary>
        /// <param name="pathType">路径类型</param>
        /// <param name="paths">待拼接的字符串集合</param>
        /// <returns>路径</returns>
        public static string Combine(PathType pathType, params string[] paths)
        {
            if (paths == null || paths.Length == 0)
            {
                return null;
            }

            OSPlatformID os = EnvironmentEx.OS;
            char separatorChar = GetPathSeparatorChar(pathType);
            char[] invalidPathChars = Path.GetInvalidPathChars();
            string path;
            var sb = new StringBuilder();
            string rootPath;
            int pathIndex;
            bool combineStart;

            for (int k = 0; k < paths.Length; k++)
            {
                path = paths[k];
                if (path == null)
                {
                    continue;
                }

                path = path.Trim();
                if (string.IsNullOrEmpty(path) ||
                    path.Length == 1 && (path[0] == LeftSlash || path[0] == RightSlash))
                {
                    if (sb.Length > 0)
                    {
                        continue;
                    }

                    if (pathType == PathType.Web ||
                        (os != OSPlatformID.Win && pathType == PathType.Local))
                    {
                        sb.Append(separatorChar);
                    }

                    continue;
                }

                if (sb.Length > 0 && sb[sb.Length - 1] != separatorChar)
                {
                    sb.Append(separatorChar);
                    pathIndex = 0;
                }
                else
                {
                    rootPath = Path.GetPathRoot(path);
                    if (string.IsNullOrWhiteSpace(rootPath))
                    {
                        pathIndex = 0;
                    }
                    else
                    {
                        if (os == OSPlatformID.Win)
                        {
                            if (path.Contains(Path.VolumeSeparatorChar))
                            {
                                pathIndex = rootPath.Length;
                                sb.Append(rootPath);
                            }
                            else
                            {
                                pathIndex = 0;
                            }
                        }
                        else
                        {
                            pathIndex = rootPath.Length;
                            sb.Append(separatorChar);
                        }
                    }
                }

                combineStart = false;

                for (int i = pathIndex; i < path.Length; i++)
                {
                    if (invalidPathChars.Contains(path[i]))
                    {
                        throw new ArgumentException($"路径中包含无效字符{path[i]}");
                    }

                    if (path[i] == LeftSlash || path[i] == RightSlash)
                    {
                        if (sb.Length == 0)
                        {
                            sb.Append(separatorChar);
                        }

                        for (int j = i + 1; j < path.Length; j++)
                        {
                            if (path[j] != LeftSlash && path[j] != RightSlash)
                            {
                                if (combineStart)
                                {
                                    sb.Append(separatorChar);
                                    combineStart = false;
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        sb.Append(path[i]);
                        combineStart = true;
                    }
                }
            }

            return sb.ToString();
        }







        /// <summary>
        /// 将路径转换为web路径
        /// </summary>
        /// <param name="path">需要转换的路径</param>
        /// <returns>web路径</returns>
        /// <exception cref="ArgumentNullException">需要转换的路径为null或空字符串或全空格将招聘异常</exception>
        public static string ToWebPath(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (EnvironmentEx.OS == OSPlatformID.Win && path.Contains(LeftSlash))
            {
                string[] strs = path.Split(new char[] { LeftSlash, RightSlash }, StringSplitOptions.RemoveEmptyEntries);
                return string.Join(RightSlash.ToString(), strs);
            }

            return path;
        }

        /// <summary>
        /// 将路径转换为本地路径
        /// </summary>
        /// <param name="path">需要转换的路径</param>
        /// <returns>本地路径</returns>
        /// <exception cref="ArgumentNullException">需要转换的路径为null或空字符串或全空格将招聘异常</exception>
        public static string ToLocalPath(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (EnvironmentEx.OS == OSPlatformID.Win && path.Contains(RightSlash))
            {
                string[] strs = path.Split(new char[] { LeftSlash, RightSlash }, StringSplitOptions.RemoveEmptyEntries);
                return string.Join(LeftSlash.ToString(), strs);
            }

            return path;
        }
    }

    /// <summary>
    /// 路径类型
    /// </summary>
    public enum PathType
    {
        /// <summary>
        /// 本地路径 
        /// </summary>
        Local,

        /// <summary>
        /// Web路径
        /// </summary>
        Web
    }
}
